package com.ruoyi.common.svgutils;

import com.ruoyi.common.utils.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * @author litao.cc
 * @version SvgUtils1.java v0.1 t2025/11/15 23:05
 * @date 2025/11/15 23:05
 * @description 处理呼西图纸,主要是找到线路，转化成我们需要的数据
 */
public class SvgUtils1 {
    public static void main(String[] args) {
        processSvg(new File("D:\\code\\track\\trackprod\\ruoyi-common\\src\\main\\java\\com\\ruoyi\\common\\svgutils\\呼西整备场站场图原始.svg"));
    }
    public static List<Line> get(){
        return processSvg(new File("D:\\code\\track\\trackprod\\ruoyi-common\\src\\main\\java\\com\\ruoyi\\common\\svgutils\\呼西整备场站场图原始.svg"));
    }
    public static List<Line> processSvg(File inputFile) {
        try {
            // 创建DOM解析器
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(inputFile);

            // 获取根元素
            Element svgElement = document.getDocumentElement();

            List<PathInfo> list = new ArrayList<>();

            NodeList pathList = svgElement.getElementsByTagName("path");
            for (int i = 0; i < pathList.getLength(); i++) {
                Element pahtElement = (Element) pathList.item(i);
                String aClass = pahtElement.getAttribute("class");
                if(StringUtils.isNotEmpty(aClass) && aClass.equals("st5")){
                    Element parentNode = (Element) pahtElement.getParentNode();
                    String transform = parentNode.getAttribute("transform");
                    if(!transform.contains("rotate")){
                        String id = parentNode.getAttribute("id");
                        PathInfo d = new PathInfo(pahtElement.getAttribute("d"), transform,id);
                        list.add(d);
                    }

                }

            }

            List<Line> lines = convertPathsToLines(list);
            return lines;
        } catch (Exception e) {
            throw new RuntimeException("处理SVG文件时出错", e);
        }
    }


    /**
     * 将PathInfo列表转换为Line列表
     */
    public static List<Line> convertPathsToLines(List<PathInfo> pathInfos) {
        List<Line> lines = new ArrayList<>();

        for (PathInfo pathInfo : pathInfos) {
            List<Line> convertedLines = convertPathToLines(pathInfo);
            lines.addAll(convertedLines);
        }

        return lines;
    }

    /**
     * 将单个PathInfo转换为Line列表
     */
    public static List<Line>  convertPathToLines(PathInfo pathInfo) {
        List<Line> lines = new ArrayList<>();

        // 解析变换参数
        TransformParams transformParams = parseTransform(pathInfo.getTransform());

        // 解析路径点
        List<Point> points = parsePathPoints(pathInfo.getD());

        // 对每个点应用变换
        List<Point> transformedPoints = applyTransform(points, transformParams);

        // 生成线段（每两个连续点形成一条线段）
        for (int i = 0; i < transformedPoints.size() - 1; i++) {
            Point p1 = transformedPoints.get(i);
            Point p2 = transformedPoints.get(i + 1);
            lines.add(new Line(p1.x, p1.y, p2.x, p2.y,pathInfo.getgId()));
        }

        return lines;
    }

    /**
     * 解析变换参数
     */
    private static TransformParams parseTransform(String transform) {
        TransformParams params = new TransformParams();

        if (transform == null || transform.trim().isEmpty()) {
            return params;
        }

        // 解析平移
        Pattern translatePattern = Pattern.compile("translate\\(([^,]+),([^)]+)\\)");
        Matcher translateMatcher = translatePattern.matcher(transform);
        if (translateMatcher.find()) {
            params.translateX = Double.parseDouble(translateMatcher.group(1).trim());
            params.translateY = Double.parseDouble(translateMatcher.group(2).trim());
        }

        // 解析旋转
        Pattern rotatePattern = Pattern.compile("rotate\\(([^)]+)\\)");
        Matcher rotateMatcher = rotatePattern.matcher(transform);
        if (rotateMatcher.find()) {
            params.rotateAngle = Double.parseDouble(rotateMatcher.group(1).trim());
        }

        return params;
    }

    /**
     * 解析路径点
     */
    private static List<Point> parsePathPoints(String pathData) {
        List<Point> points = new ArrayList<>();

        if (pathData == null || pathData.trim().isEmpty()) {
            return points;
        }

        // 匹配 M 或 L 命令后的坐标对
        Pattern pattern = Pattern.compile("[ML]\\s*([-]?\\d+\\.?\\d*)\\s+([-]?\\d+\\.?\\d*)");
        Matcher matcher = pattern.matcher(pathData);

        while (matcher.find()) {
            double x = Double.parseDouble(matcher.group(1));
            double y = Double.parseDouble(matcher.group(2));
            points.add(new Point(x, y));
        }

        return points;
    }

    /**
     * 对点列表应用变换
     */
    private static List<Point> applyTransform(List<Point> points, TransformParams params) {
        List<Point> transformedPoints = new ArrayList<>();

        for (Point point : points) {
            // 先应用平移
            double x = point.x + params.translateX;
            double y = point.y + params.translateY;

            // 如果有旋转，应用旋转变换
            if (params.rotateAngle != 0) {
                double angleRad = Math.toRadians(params.rotateAngle);
                double cos = Math.cos(angleRad);
                double sin = Math.sin(angleRad);

                double rotatedX = x * cos - y * sin;
                double rotatedY = x * sin + y * cos;

                x = rotatedX;
                y = rotatedY;
            }

            transformedPoints.add(new Point(x, y));
        }

        return transformedPoints;
    }

    /**
     * 变换参数内部类
     */
    private static class TransformParams {
        double translateX = 0;
        double translateY = 0;
        double rotateAngle = 0;
    }

    /**
     * 点坐标内部类
     */
    private static class Point {
        double x;
        double y;

        Point(double x, double y) {
            this.x = x;
            this.y = y;
        }
    }
    static class PathInfo {
        String d;
        String transform;
        String gId;

        PathInfo(String d, String transform,String gId) {
            this.d = d;
            this.transform = transform;
            this.gId = gId;
        }
        public String getD() { return d; }
        public void setD(String d) { this.d = d; }
        public String getTransform() { return transform; }
        public void setTransform(String transform) { this.transform = transform; }

        public String getgId() {
            return gId;
        }

        public void setgId(String gId) {
            this.gId = gId;
        }

        @Override
        public String toString() {
            return "d:"+d +"  ,  " + "transform:" +transform   ;
        }
        //+"  ,  " + "gId:" +gId
    }

    // 输出数据模型
    public static class Line {
        private double x1;
        private double y1;
        private double x2;
        private double y2;

        private String oid;

        Line(double x1, double y1, double x2, double y2,String oid) {
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
            this.oid = oid;
        }

        // getters and setters
        public double getX1() { return x1; }
        public void setX1(double x1) { this.x1 = x1; }
        public double getY1() { return y1; }
        public void setY1(double y1) { this.y1 = y1; }
        public double getX2() { return x2; }
        public void setX2(double x2) { this.x2 = x2; }
        public double getY2() { return y2; }
        public void setY2(double y2) { this.y2 = y2; }

        public String getOid() {
            return oid;
        }

        public void setOid(String oid) {
            this.oid = oid;
        }

        @Override
        public String toString() {
            return String.format("Line{x1=%.2f, y1=%.2f, x2=%.2f, y2=%.2f}", x1, y1, x2, y2);
        }
    }
}

